/**
 * @Author 天下无敌
 * @Date 
 * @AIDE AIDE+ 
 */
package com.ecs.core.gsystem.draw;
import com.artemis.annotations.All;
import com.artemis.ComponentMapper;
import com.ecs.core.gsystem.CameraSystem;
import com.ecs.core.gsystem.RenderContextSystem;
import com.badlogic.gdx.math.Rectangle;
import static com.ecs.core.GameContext.metersToPixels;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.Color;
import com.ecs.core.system.abs.BaseCullingSystem;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.ecs.core.components.draw.SpriteRender;
import com.ecs.core.components.attribute.Transform;
@All({SpriteRender.class,Transform.class})
public class SpriteRenderSystem extends BaseCullingSystem
{

	private ComponentMapper<Transform> transforms;
	private ComponentMapper<SpriteRender> sprites;
	private CameraSystem cameraSystem;
	private RenderContextSystem renderContext;
	private final Rectangle entityBounds = new Rectangle();
	@Override
	protected void initialize()
	{
		super.initialize();
		//setEnabled(false);
	}

	
	@Override
	protected void begin()
	{
		super.begin();
		renderContext.batchBegin();
	}

	@Override
	protected void end()
	{
		super.end();
		renderContext.batchEnd();
		
	}

	@Override
	protected void process(int entityId)
	{
		Rectangle rect = entityRect(entityId);
		SpriteRender sprite = sprites.get(entityId);
		Transform transform = transforms.get(entityId);

		Batch batch = renderContext.getBatch();
		
		ShaderProgram originalShader = batch.getShader();

        if(sprite.customShader != null) {
            batch.setShader(sprite.customShader);
			float minU = sprite.region.getU();
			float minV = sprite.region.getV();
			float maxU = sprite.region.getU2();
			float maxV = sprite.region.getV2();
			batch.getShader().setUniformf("u_region",minU,minV,maxU,maxV);
        }
		
		Color color = sprite.color;
		TextureRegion region = sprite.region;
		region.flip(sprite.flipX,sprite.flipY);

		float ox = metersToPixels(sprite.originX);
		float oy = metersToPixels(sprite.originY);

		float rotation = transform.getRotationX();//2dx
		
		batch.setColor(color);
		batch.draw(region,rect.getX()
		,rect.getY()
		,ox,oy,
		rect.getWidth(),
		rect.getHeight(),
		1,1,
		rotation);
		
		batch.setShader(originalShader);
	}

	protected boolean isCulling(int entityId)
	{
		cameraSystem.updata();
		return cameraSystem.overlaps(entityRect(entityId)) && sprites.get(entityId).isActives;
	}

	public Rectangle entityRect(int entityId){
		Transform t = transforms.get(entityId);
		float x = metersToPixels(t.getPosX());
		float y = metersToPixels(t.getPosY());
		float w = metersToPixels(t.getScaleX());
		float h = metersToPixels(t.getScaleY());
		entityBounds.set(x,y,w,h);
		return entityBounds;
	}


	@Override
	protected void optimizedBubbleSort() {
		activesEntityIds.sort((e1, e2) -> {
			SpriteRender a1 = sprites.get(e1);
			SpriteRender a2 = sprites.get(e2);
			int zCompare = Integer.compare(a1.sortingOrder, a2.sortingOrder);
			if(zCompare!= 0){return zCompare;}
			
			Transform t1 = transforms.get(e1);
			Transform t2 = transforms.get(e2);
			return Float.compare(t2.getPosY(), t1.getPosY());
		});
	}
}
